package com.wjy.common.log.service;

import com.wjy.common.build.LogMessageBuild;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @author ybxxszl
 * @desc 服务日志
 * @date 2019/4/16
 */
@Component
@Log4j2
@Aspect
public class ServiceLog {

    /**
     * @desc 定义切入点
     */
    @Pointcut(value = "execution(* com.wjy.qs.service.impl..*.*(..))")
    public void serviceLog() {

    }

    /**
     * @param point
     * @desc 前置：方法执行之前执行
     */
    @Before(value = "serviceLog()")
    public void doBefore(JoinPoint point) {
        log.info("前置");
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        Signature signature = point.getSignature();
        LogMessageBuild build = new LogMessageBuild(request, point, signature);
        log.info(build.toRequestString());
        log.info(build.toJavaString());
    }

    /**
     * @param point
     * @param result
     * @desc 后置返回：方法返回之后执行
     */
    @AfterReturning(value = "serviceLog()", returning = "result")
    public void doAfterReturning(JoinPoint point, Object result) {
        log.info("后置返回");
        LogMessageBuild build = new LogMessageBuild(result);
        log.info(build.toResultString());
    }

    /**
     * @param point
     * @param exception
     * @desc 后置异常：方法抛出异常之后执行
     */
    @AfterThrowing(value = "serviceLog()", throwing = "throwable")
    public void doAfterThrowing(JoinPoint point, Throwable throwable) {
        log.info("后置异常");
        LogMessageBuild build = new LogMessageBuild(throwable);
        log.info(build.toThrowableString());
    }

    /**
     * @param point
     * @desc 后置：方法执行之后执行
     */
    @After(value = "serviceLog()")
    public void doAfter(JoinPoint point) {
        log.info("后置");
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        Signature signature = point.getSignature();
        LogMessageBuild build = new LogMessageBuild(request, point, signature);
        log.info(build.toRequestString());
        log.info(build.toJavaString());
    }

    /**
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     * @desc 环绕：方法执行之前或方法执行之后的自定义执行
     */
    @Around(value = "serviceLog()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        log.info("环绕");
        long startTime = System.currentTimeMillis();
        Object object = proceedingJoinPoint.proceed();
        long endTime = System.currentTimeMillis();
        log.info("执行时间：" + (endTime - startTime) + "ms");
        return object;
    }

}
